package com.faxsun.common.file.service;

import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.tools.view.ImportSupport;
import org.broadleafcommerce.common.file.service.StaticAssetPathServiceImpl;
import org.broadleafcommerce.common.web.BroadleafRequestContext;

import javax.servlet.http.HttpServletRequest;

public class FSStaticAssetPathServiceImpl extends StaticAssetPathServiceImpl {

    /**
     * This method will take in a content string (e.g. StructuredContentDTO or PageDTO HTML/ASSET_LOOKUP/STRING field value)
     * and replace any instances of "staticAssetUrlPrefix" in the string with the "staticAssetEnvironmentUrlPrefix"
     * or the "staticAssetEnvironmentSecureUrlPrefix" depending on if the request was secure and if it was configured.
     * <p/>
     * Override this method the orginal implementation will throw illegal param exception under Windows env
     * <p/>
     * Given asset.server.url.prefix.internal=cmsstatic
     * Given asset.server.url.prefix=http://static.mydomain.com/cmsstatic
     * Given asset.server.url.prefix.secure=https://static.mydomain.com/cmsstatic
     * <p/>
     * Example 1:
     * Given content = "<p><img src="/cmsstatic/my_image.jpg"/></p>"
     * <p/>
     * The result should yield: "<p><img src="http://static.mydomain.com/cmsstatic/my_image.jpg"/></p>"
     * <p/>
     * Example 2:
     * Given content = "<p><img src="cmsstatic/my_image_2.jpg"/></p>"
     * <p/>
     * The result should yield: "<p><img src="http://static.mydomain.com/cmsstatic/my_image_2.jpg"/></p>"
     *
     * @param content       - The content string to rewrite if it contains a cms managed asset
     * @param secureRequest - True if the request is being served over https
     * @return
     * @see org.broadleafcommerce.common.file.service.StaticAssetService#getStaticAssetUrlPrefix()
     * @see org.broadleafcommerce.common.file.service.StaticAssetService#getStaticAssetEnvironmentUrlPrefix()
     */
    @Override
    public String convertAllAssetPathsInContent(String content, boolean secureRequest) {
        String returnValue = content;

        if (StringUtils.isNotBlank(content) &&
            StringUtils.isNotBlank(getStaticAssetUrlPrefix()) &&
            content.contains(getStaticAssetUrlPrefix())) {

            String envPrefix = null;
            if (secureRequest) {
                envPrefix = getStaticAssetEnvironmentSecureUrlPrefix();
            } else {
                envPrefix = getStaticAssetEnvironmentUrlPrefix();
            }
            if (envPrefix != null && envPrefix.endsWith("/")) {
                envPrefix = envPrefix.substring(0, envPrefix.length() - 1);
                // Remove the "/" from the end of envPrefix, since contextPath always starts with "/".
            }

            String contextPath = "";
            BroadleafRequestContext brc = BroadleafRequestContext.getBroadleafRequestContext();
            if (brc != null) {
                HttpServletRequest request = brc.getRequest();
                if (request != null) {
                    contextPath = request.getContextPath();
                }
            }

            if (!contextPath.endsWith("/")) {
                contextPath = contextPath + "/";
            }

            envPrefix = StringUtils.isEmpty(envPrefix) ? contextPath : envPrefix + contextPath;

//            if (staticAssetUrlPrefix == null)
//                staticAssetUrlPrefix = BLCSystemProperty.resolveSystemProperty("asset.server.url.prefix.internal");
//
//            if (staticAssetUrlPrefix != null) {
//                String tmpPrefix = staticAssetUrlPrefix;
//                if (tmpPrefix.startsWith("/")) {
//                    tmpPrefix = tmpPrefix.substring(1);
//                }
//                return longDescription.replaceAll("(?<=src=\").*?(?=" + tmpPrefix + ")", contextPath);
//            }

            //returnValue = returnValue.replaceAll(getStaticAssetUrlPrefix() + trailing, envPrefix);
            returnValue = returnValue.replaceAll("(?<=src=\").*?(?=" + getStaticAssetUrlPrefix() + ")", envPrefix);
            //Catch any scenario where there is a leading "/" after the replacement
            //returnValue = returnValue.replaceAll("/" + envPrefix.toString(), envPrefix.toString());
        }

        return returnValue;
    }

    /**
     * This method will take in an assetPath (think image url) and prepend the
     * staticAssetUrlPrefix if one exists.
     * <p/>
     * Will append any contextPath onto the request. If the incoming assetPath
     * contains the internalStaticAssetPrefix and the image is being prepended,
     * the prepend will be removed.
     * <p/>
     * Example 1: Given asset.server.url.prefix.internal=cmsstatic Given
     * asset.server.url.prefix=http://static.mydomain.com/ Given
     * asset.server.url.prefix.secure=https://static.mydomain.com/ Given
     * request.getContextPath() = /shop Given assetPath =
     * "/cmsstatic/my_image.jpg"
     * <p/>
     * The result should yield:
     * "http://static.mydomain.com/shop/cmsstatic/my_image.jpg"
     * <p/>
     * Example 2: Given asset.server.url.prefix.internal=cmsstatic Given
     * asset.server.url.prefix= Given asset.server.url.prefix.secure= Given
     * assetPath = "/cmsstatic/my_image.jpg" Given contextPath = "myApp"
     * <p/>
     * The result should yield: "/myApp/cmsstatic/my_image.jpg"
     * <p/>
     * Also, since all paths are intended to be URLs, there should be no
     * system-specific separator characters like '\' for Windows. All paths
     * should be unix file paths as URLs.
     *
     * @param assetPath     - The path to rewrite if it is a cms managed asset
     * @param contextPath   - The context path of the web application (if applicable)
     * @param secureRequest - True if the request is being served over https
     * @return
     * @see org.broadleafcommerce.common.file.service.StaticAssetService#getStaticAssetUrlPrefix()
     * @see org.broadleafcommerce.common.file.service.StaticAssetService#getStaticAssetEnvironmentUrlPrefix()
     */
    @Override
    public String convertAssetPath(String assetPath, String contextPath, boolean secureRequest) {
        String returnValue = assetPath;

        if (assetPath != null && getStaticAssetEnvironmentUrlPrefix() != null
            && !"".equals(getStaticAssetEnvironmentUrlPrefix())) {
            String envPrefix;
            if (secureRequest) {
                envPrefix = getStaticAssetEnvironmentSecureUrlPrefix();
            } else {
                envPrefix = getStaticAssetEnvironmentUrlPrefix();
            }
            if (envPrefix != null) {
                // Attach the contextPath if it exists.
                if (contextPath != null)
                    returnValue = contextPath + returnValue;

                // remove the starting "/" if it exists.
                if (returnValue.startsWith("/")) {
                    returnValue = returnValue.substring(1);
                }

                if (envPrefix.endsWith(getStaticAssetUrlPrefix() + "/")) {
                    envPrefix = envPrefix.substring(0, envPrefix.length()
                        - getStaticAssetUrlPrefix().length() - 1);
                }

                returnValue = envPrefix + returnValue;
            }
        } else {
            if (returnValue != null && !ImportSupport.isAbsoluteUrl(returnValue)) {
                if (!returnValue.startsWith("/")) {
                    returnValue = "/" + returnValue;
                }

                // Add context path
                if (contextPath != null && !contextPath.equals("")) {
                    if (!contextPath.equals("/")) {
                        // Shouldn't be the case, but let's handle it anyway
                        if (contextPath.endsWith("/")) {
                            returnValue = returnValue.substring(1);
                        }
                        if (contextPath.startsWith("/")) {
                            returnValue = contextPath + returnValue; // normal
                            // case
                        } else {
                            returnValue = "/" + contextPath + returnValue;
                        }
                    }
                }
            }
        }

        return returnValue;
    }
}
